import React,{
    PureComponent
} from 'react';

import PropTypes from 'prop-types';

import {
    Loading
} from './../../components';

interface Props {
    page: number,
    selectedPage: number
}

interface State {
    created: boolean,
    loading: boolean,
}

class TabContent extends PureComponent<Props, State> {
    timer: any = null;
    pageIn:boolean=false;
    listens:Array<Function> = [];
    listensOut:Array<Function> = [];

    static defaultProps = {
        page: 0,
        selectedPage: 0
    }

    constructor(props: Props) {
        super(props);
        this.pageIn = (
            this.checkSelected(props)
        )
        this.state = {
            loading: false,
            created: this.pageIn
        }
    }

    static childContextTypes = {
        listenTabIn:PropTypes.func,
        listenTabOut:PropTypes.func,
        removeTabIn:PropTypes.func,
        removeTabOut:PropTypes.func
    }

    getChildContext() {
        return {
            listenTabIn:this.listenTabIn,
            listenTabOut:this.listenTabOut,
            removeTabIn:this.removeTabIn,
            removeTabOut:this.removeTabOut
        }
    }

    private listenTabIn = (func:Function) => {
        this.listens.push(func);
    }

    private listenTabOut = (func:Function) => {
        this.listensOut.push(func);
    }

    private removeTabIn = (func:Function) => {
        this.removeLister(this.listens,func);
    }

    private removeTabOut = (func:Function) => {
        this.removeLister(this.listensOut,func);
    }

    private removeLister = (
        fns:Array<Function>,
        func:Function
    ) => {
        const index = (
            fns.findIndex(fn => (
                fn === func
            ))
        )
        if(index > -1) {
            fns.splice(index,1);
        }
    }

    componentDidUpdate() {
        const {
            created,
            loading
        } = this.state;

        const isSelected = (
            this.checkSelected()
        )

        if(created) {
            this.hookPage(isSelected);
            this.pageIn = isSelected;
            return false;
        }

        if(loading) {
            return false;
        }

        if(isSelected) {
            this.onPageCreated();
        }
    }

    private hookPage = (isSelected:boolean) => {
        if(!isSelected || this.pageIn) {
            return this.eachFns(this.listensOut)
        }
        this.eachFns(this.listens);
    }

    private eachFns = (fns:Array<Function>) => {
        fns.forEach(fn => fn());
    }

    private delay = () => (
        new Promise(resolve => {
            this.timer = setTimeout(resolve, 200)
        })
    )

    private checkSelected = (props?: Props) => {
        const {
            page,
            selectedPage
        } = props || this.props;
        return page === selectedPage;
    }

    private onPageCreated = async () => {
        this.setState({
            loading: true
        })
        await this.delay();
        this.setState({
            loading: false,
            created: true
        })
    }

    componentWillUnmount() {
        if (!!this.timer) {
            clearTimeout(this.timer);
        }
    }

    render() {
        const {
            created,
            loading
        } = this.state;

        const {
            children
        } = this.props;

        if (created) {
            return children;
        }

        return loading ? <Loading.container/> : null;
    }
}

export default TabContent;